<?php
namespace Snitso\IO\AsyncModel;

/**
 * Note: 单线程 Reactor 模型
 * Reactor => epoll
 *
 * @author:  Zhao Zhiqiang
 * @since:   2021/5/2 11:12
 * @version: 1.0
 *
 * @package Snitso\IO\AsyncModel
 */
class Worker
{
    /**
     * @var resource $socket
     */
    protected $socket;

    /**
     * @var \Closure
     */
    public $onConnect;

    /**
     * @var \Closure
     */
    public $onReceive;

    public function __construct(string $localSocket)
    {
        $socket = stream_socket_server($localSocket, $errno, $errstr);

        if (! $socket) {
            echo $errstr . PHP_EOL;
            exit;
        }

        $this->socket = $socket;
    }

    public function start()
    {
        $this->accept();
    }

    protected function accept()
    {
        echo "到这里了" . PHP_EOL;
        \Swoole\Event::add($this->socket, function ($socket) {
            $conn = stream_socket_accept($this->socket);

            if ($conn === false) {
                echo '连接失败' . PHP_EOL;
                exit;
            }

            ($this->onConnect)($this, $conn);

            \Swoole\Event::add($conn, function ($conn) {
                $data = fread($conn, 1024);

                if (! $data || ! trim($data) || feof($conn)) {
                    swoole_event_del($conn);
                    fclose($conn);

                    return;
                }

                ($this->onReceive)($this, $conn, $data);
            });
        });

        echo "结束了" . PHP_EOL;
    }

    public function send($conn, string $content)
    {
        $response = "HTTP/1.1 200 OK\r\n";
        $response .= "Content-Type: text/html;charset=UTF-8\r\n";
        $response .= "Connection: keep-alive\r\n";
        $response .= "Content-length: ".strlen($content)."\r\n\r\n";
        $response .= $content;
        fwrite($conn, $response);
    }
}